/*
 *  Copyright (C) 2011 glauco
 * 
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 * 
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 * 
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.balisunrise.swing.builders;

import javax.swing.JPanel;
import org.balisunrise.annotation.EventType;
import org.balisunrise.annotation.VisualActionTarget;
import org.balisunrise.annotation.util.AnnotationsUtilitiesException;
import org.balisunrise.annotation.util.EditorUtilities;
import org.balisunrise.annotation.util.NameUtil;
import org.balisunrise.application.Application;
import org.balisunrise.builder.BuilderException;
import org.balisunrise.common.Action;
import org.balisunrise.common.ActionProvider;
import org.balisunrise.common.Editor;
import org.balisunrise.common.EntityActions;
import org.balisunrise.common.EntityPanel;
import org.balisunrise.common.Messenger;
import org.balisunrise.common.VisualAction;
import org.balisunrise.swing.commons.listeners.EntityActionsListener;
import org.balisunrise.swing.components.panel.EditorPanel;
import org.balisunrise.swing.components.panel.layouts.EditorLayoutBuilder;

/**
 *
 * @author glauco
 */
public class EditorBuilder implements org.balisunrise.builder.EditorBuilder{

    private static final String MESSAGE = "Erro ao construir uma Editor.\n";

    @Override
    public Editor create(Class entityClass, String alias)
            throws BuilderException {

        if(entityClass == null){
            throw new BuilderException(MESSAGE +
                    "entityClass não pode ser nulo.");
        }

        if(alias == null){
            throw new BuilderException(MESSAGE +
                    "alias não pode ser nulo.");
        }

        try{
            EditorUtilities eu = EditorUtilities.create(entityClass, alias);
            return create(eu);
        }catch(AnnotationsUtilitiesException aue){
            throw new BuilderException(MESSAGE +
                    aue.getMessage(), aue.getCause());
        }
    }

    @Override
    public Editor create(EditorUtilities eu) throws BuilderException {

        if(eu == null){
            throw new BuilderException(MESSAGE +
                    "editorUtilities não pode ser nulo.");
        }

        // cria editor
        org.balisunrise.swing.commons.Editor editor =
                new org.balisunrise.swing.commons.Editor();

        // atribuições
        editor.setAlias(eu.alias);
        editor.setEntityClass(eu.entityClass);
        editor.setTitle(eu.title);

        // constrói Messenger
        Messenger<JPanel> messenger = Application.get()
                .getVisualEntityManager()
                .getMessengerBuilder()
                .create(eu.entityClass,
                        eu.alias);

        // constrói EntityPanel
        EntityPanel<JPanel> ep = Application.get()
                .getVisualEntityManager()
                .getEntityPanelBuilder()
                .create(eu.panelUtilities);

        // constrói EntityActions
        EntityActions<VisualAction,JPanel> ea = Application.get()
                .getVisualEntityManager()
                .getEntityActionBuilder()
                .create(eu.entityClass,
                        eu.alias);

        // Cria as Ações Visuais
        ActionProvider ap = Application.get()
                .getActionMapManager()
                .getActionProvider(eu.entityClass);
        VisualAction[] vas = ap.getVisualActions(
                VisualActionTarget.EDITOR, eu.alias, null);
        // adiciona as ações visuais ao painel de ações
        for (VisualAction va : vas) {
            va.setOwner(ea);
            ea.addAction(va);
        }

        // Cria o listener das ações
        EntityActionsListener eal = new EntityActionsListener();
        ea.addEntityActionsListener(eal);

        // cria as ações de um evento visual
        Action[] as = ap.getActions(EventType.VISUAL_SEARCH, eu.alias, null);
        for (Action action : as) {
            action.setOwner(ea);
            eal.addVisualActinPerformedAction(action);
        }

        // cria as ações de eventos antes de confirmar
        as = ap.getActions(EventType.ENTITY_ACTION_BEFORE_CONFIRM,
                eu.alias, null);
        for (Action action : as) {
            action.setOwner(ea);
            eal.addBeforeConfirmAction(action);
        }

        // cria as ações de eventos antes de cancelar
        as = ap.getActions(EventType.ENTITY_ACTION_BEFORE_CANCEL,
                eu.alias, null);
        for (Action action : as) {
            action.setOwner(ea);
            eal.addBeforeCancelAction(action);
        }

        // atruibui o pai
        messenger.setOwner(editor);
        ep.setOwner(editor);
        ea.setOwner(editor);

        // cria representação visual
        EditorPanel panel = new EditorPanel(
                messenger.getVisualRepresentation(),
                ep.getVisualRepresentation(),
                ea.getVisualRepresentation(),
                new EditorLayoutBuilder());

        // atribuições
        editor.setMessenger(messenger);
        editor.setEntityPanel(ep);
        editor.setEntityActions(ea);
        editor.setVisualRepresentation(panel);

        // nome do painel
        String name = NameUtil.buildName(editor);
        editor.getVisualRepresentation().setName(name);
        editor.getVisualRepresentation().getAccessibleContext()
                .setAccessibleName(name);
        editor.setName(name);

        return editor;
    }
}
